<template>
  <div class="hello">
    <div>{{ origin }}</div>
    <div>
      数学：<el-input v-model="input" placeholder="请输入内容"/>
      语文：<el-input v-model="input1" placeholder="请输入内容"/>
      英语：<el-input v-model="input2" placeholder="请输入内容"/>
      总数：{{ total }}
    </div>
    <div>
      姓：<input type="text" placeholder="firstName" v-model="firstName"><br>
      名：<input type="text" placeholder="lastName" v-model="lastName"><br>
      <!-- 姓名1(单向):<input type="text" placeholder="FullName1" v-model="fullName1"><br> -->
      姓名2(双向):<input type="text" placeholder="FullName2" v-model="fullName3"><br>
      watch: <input type="text" placeholder="firstName" v-model="isColor.aa"><br>
      isWatch: <el-input v-model="isWatch1" placeholder="请输入内容"/>
    </div>
    <el-input v-model="modele" placeholder="请输入内容"/>
    <span>{{ modele | SEX_SHOW }}</span>
  </div>
</template>

<script>
import {
  DEEP_CLONE
} from '@/utils/constants'
export default {
  name: 'origin',
  data () {
    return {
      origin: 'origin',
      input: 20,
      input1: 30,
      input2: 40,
      input3: 0,
      firstName: 'A',
      lastName: 'B',
      fullName2: 'A B',
      isColor: {
        aa: 'red',
        bb: 'black'
      },
      isWatch1: 'isWatch',
      obj: {
        a: 123
      },
      modele: 0
    }
  },
  // watch主要用于监控vue实例的变化，它监控的变量当然必须在data里面声明才可以，它可以监控一个变量，也可以是一个对象
  // watch一般用于监控路由、input输入框的值特殊处理等等，它比较适合的场景是一个数据影响多个数据
  watch: {
    // watch 方法最初绑定的时候，它是不会执行的，只有变化了才会执行
    'isColor.aa' () {
      console.log(this.isColor.aa)
    },
    isWatch1: {
      // 声明一个handler，这样在初始化时就会执行一次 handler
      handler (val) {
        console.log(val)
      },
      immediate: true
    },
    obj: {
      handler () {
        console.log('obj.a changed')
      },
      immediate: true,
      deep: true // 如果不加这一句，在输入框中输入值，并不会打印 obj.a changed
    }
  },
  // computed用来监控自己定义的变量，该变量不在data里面声明，直接在computed里面定义，然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理
  // computed比较适合对多个变量或者对象进行处理后返回一个结果值，也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化
  // 在Vue中计算属性是基于它们的依赖进行缓存的，而方法是不会基于它们的依赖进行缓存的。从而使用计算属性要比方法性能更好。
  // computed是属性调用,computed带有缓存功能
  // computed 是一个对象时，它有哪些选项？
  // computed 和 methods 有什么区别？
  // computed 是否能依赖其它组件的数据？
  // watch 是一个对象时，它有哪些选项？
  // -有get和set两个选项
  // -methods是一个方法，它可以接受参数，而computed不能，computed是可以缓存的，methods不会。
  // -computed可以依赖其他computed，甚至是其他组件的data
  // -watch 配置
  // -handler
  // -deep 是否深度
  // -immeditate 是否立即执行
  // 双向绑定
  // 1）数据属性，就是我们经常使用的属性（2）访问器属性，也称存取器属性（存取器属性就是一组获取和设置值的函数）
  // get和set就是关键字 它们后面各自对应一个函数，这个函数就是上面红字部分所讲的，存储器属性。
  // get对应的方法称为getter，负责获取值，它不带任何参数。set对应的方法为setter，负责设置值，在它的函数体中，一切的return都是无效的。
  // 通过Object.defineProperty()来劫持各个属性的setter，getter，在数据变动时发布消息给订阅者，触发相应的监听回调。
  // render()渲染--https://my.oschina.net/dtdths/blog/1583590
  computed: {
    total () {
      let totals = 0
      totals = parseFloat(this.input) + parseFloat(this.input1) + parseFloat(this.input2)
      console.log(totals)
      return totals
    },
    fullName1 () { // 计算属性中的get方法，方法的返回值就是属性值
      return this.firstName + ' ' + this.lastName
    },
    fullName3: {
      get () { // 回调函数 当需要读取当前属性值是执行，根据相关数据计算并返回当前属性的值
        return this.firstName + ' ' + this.lastName
      },
      set (val) { // 监视当前属性值的变化，当属性值发生变化时执行，更新相关的属性数据
        // val就是fullName3的最新属性值
        console.log(val)
        const names = val.split(' ')
        console.log(names)
        this.firstName = names[0]
        this.lastName = names[1]
      }
    }
  },
  mounted () {
    console.log(4)
    let aa = {
      a: 1
    }
    let bb = {
      b: 2
    }
    bb = DEEP_CLONE(aa)
    aa.a = 3
    console.log(bb)
    console.log(aa)
  },
  methods: {
  }
}
</script>
<style lang="less">
  .el-input {
    width: 20%
  }
</style>
